﻿using System.Linq;
using System.Text.RegularExpressions;

namespace Charades.Web.Controllers
{
	using System;
	using System.Threading.Tasks;
	using System.Web;
	using System.Web.Mvc;

	using CaptchaMvc.HtmlHelpers;

	using Charades.Web.Hubs;
	using Charades.Web.Server;

	using Helpers;

	using Microsoft.AspNet.Identity;
	using Microsoft.AspNet.Identity.EntityFramework;
	using Microsoft.AspNet.SignalR;

	using Models;

	public class HomeController : Controller
	{
		public HomeController()
		{
			UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
			GameInstance = Web.Server.Game.Instance;
		}

		public UserManager<ApplicationUser> UserManager { get; private set; }

		public Game GameInstance { get; set; }

		public static IHubContext GetHubContext()
		{
			return GlobalHost.ConnectionManager.GetHubContext<GameHub>();
		}

		public async Task<ActionResult> Index()
		{
			if (!User.Identity.IsAuthenticated)
			{
				return View();
			}

			if (Response.Cookies.AllKeys.Contains("Welcome"))
			{
				Response.Cookies.Remove("Welcome");
			}

			var user = await UserManager.FindByNameAsync(User.Identity.Name);
			return View(user);
		}

		[AjaxOnly]
		public ActionResult Logon()
		{
			return View();
		}

		[AjaxOnly]
		public ActionResult Intro()
		{
			return View();
		}

		[AjaxOnly]
		public ActionResult Game()
		{
			return View();
		}

		[AjaxOnly]
		[System.Web.Mvc.Authorize]
		[ActionName("Profile")]
		public async Task<ActionResult> ProfileAction()
		{
			var user = await UserManager.FindByNameAsync(User.Identity.Name);
			return View("Profile", user);
		}

		public ActionResult About()
		{
			return View();
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public ActionResult About(FeedbackViewModel model)
		{
			if (ModelState.IsValid && this.IsCaptchaValid("Captcha error"))
			{
				MailHelper.SendFeedback(model.Email, model.Content);

				ViewBag.Message = "Ваше сообщение отправлено";

				return View();
			}
			return View(model);
		}

		[AjaxOnly]
		[HttpPost]
		[ValidateAntiForgeryToken]
		public void UploadImage(string connectionId, string name, string imageData)
		{
			if (string.IsNullOrEmpty(connectionId) || string.IsNullOrEmpty(name) || string.IsNullOrEmpty(imageData))
			{
				return;
			}

			if (GameInstance.UserHandler.UserExists(connectionId))
			{
				var room = GameInstance.RoomHandler.GetRoom(connectionId);
				GetHubContext().Clients.Group(room.Id).imageUrl(new { url = new Uri(ServerSettings.RootUrl, name.Substring(0, 8)) });
			}

			FileHelper.SavePicture(name, imageData);
		}

		public ActionResult Picture(string id)
		{
			var model = FileHelper.GetPicture(id);

			if (model == null)
			{
				throw new HttpException(404, "Page not found");
			}

			return View(model);
		}

		public ActionResult Feed()
		{
			return View(FileHelper.GetPictureList());
		}

		[AjaxOnly]
		[HttpPost]
		[ValidateAntiForgeryToken]
		public JsonResult LoadFeed(int page)
		{
			return Json(FileHelper.GetPictureList(page));
		}

		[AjaxOnly]
		[HttpPost]
		[ValidateAntiForgeryToken]
		public JsonResult CheckRoom(string roomId)
		{
			return Json(new { success = GameInstance.RoomHandler.CheckRoom(roomId) });
		}

		[AjaxOnly]
		[HttpPost]
		[System.Web.Mvc.Authorize]
		[ValidateAntiForgeryToken]
		public void ChangeName(string name)
		{
			if (string.IsNullOrEmpty(name) || !Regex.IsMatch(name, "^[А-яA-z0-9_-]{3,15}$"))
			{
				return;
			}

			var user = UserManager.FindByName(User.Identity.Name);
			user.DisplayName = name;
			UserManager.Update(user);
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && UserManager != null)
			{
				UserManager.Dispose();
				UserManager = null;
			}
			base.Dispose(disposing);
		}
	}
}